package com.tengju.user.application.login;

import com.tengju.user.application.shared.Constant;
import com.tengju.user.application.login.vo.CheckSmsCodeVO;
import com.tengju.user.application.shared.ApplicationException;
import com.tengju.user.application.shared.ApplicationExceptionCode;
import com.tengju.user.application.sms.SmsBizService;
import com.tengju.user.domain.model.login.UserType;
import com.tengju.user.domain.model.sms.*;
import com.tengju.user.domain.service.SmsBaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.UUID;


@Service
@Slf4j
public class SmsVerifyCodeService {

    @Value("${system.env}")
    String env;


    private SmsBizService smsBizService;
    private SmsVerifyCodeRepository smsVerifyCodeRepository;
    private SmsBaseService smsBaseService;

    @Autowired
    public SmsVerifyCodeService(SmsBizService smsBizService, SmsVerifyCodeRepository smsVerifyCodeRepository, SmsBaseService smsBaseService) {
        this.smsBizService = smsBizService;
        this.smsVerifyCodeRepository = smsVerifyCodeRepository;
        this.smsBaseService = smsBaseService;
    }

    /**
     * 短信验证码校验
     */
    public ManMachineValidateRegister geetestRegister() {
        return smsBaseService.manMachineVerificationRegister();
    }

    /**
     * 发送短信验证码
     */
    public boolean sendSmsVerifyCode(SendSmsVerifyCodeData sendSmsVerifyCodeData,boolean needGeetest) {

        if (needGeetest) {
            ManMachineValidateData manMachineValidateData = new ManMachineValidateData(sendSmsVerifyCodeData.getChallenge(),
                    sendSmsVerifyCodeData.getValidate(),
                    sendSmsVerifyCodeData.getSecCode());

            boolean geetestCheckResult = smsBaseService.manMachineVerification(manMachineValidateData);
            if (!geetestCheckResult) {
                throw ApplicationException.error(ApplicationExceptionCode.GEETEST_CHECK_FAIL);
            }
        }

        //校验一分钟内是否以获取过验证码
        boolean checkResult = smsVerifyCodeRepository.checkLimitTime(sendSmsVerifyCodeData.getUserType(),
                sendSmsVerifyCodeData.getOperationType(),
                sendSmsVerifyCodeData.getAreaCode(),
                sendSmsVerifyCodeData.getMobile(),
                Constant.SMS_LIMIT_TIME);

        if (checkResult) {

            //生成4位数验证码
            SmsVerifyCode smsVerifyCode = SmsTempFactory.fourSmsCode(sendSmsVerifyCodeData.getMobile(), sendSmsVerifyCodeData.getAreaCode());

            //发送验证码
            if (!smsBizService.sendSmsVerifyCode(smsVerifyCode)) {
                log.error("sendSmsVerifyCode error,mobile:{}",sendSmsVerifyCodeData.getMobile());
                throw ApplicationException.error(ApplicationExceptionCode.SMS_CODE_SEND_FAIL);
            }

            return smsVerifyCodeRepository.saveSmsVerifyCode(sendSmsVerifyCodeData.getUserType(),
                    sendSmsVerifyCodeData.getOperationType(),
                    sendSmsVerifyCodeData.getAreaCode(),
                    sendSmsVerifyCodeData.getMobile(),
                    smsVerifyCode.getVerifyCode(),
                    Constant.SMS_CODE_EXPIRE_TIME);

        } else {
            //剩余ttl时间
            Long remainLimitTime = smsVerifyCodeRepository.remainLimitTime(sendSmsVerifyCodeData.getUserType(),
                    sendSmsVerifyCodeData.getOperationType(),
                    sendSmsVerifyCodeData.getAreaCode(),
                    sendSmsVerifyCodeData.getMobile());
            throw ApplicationException.error(ApplicationExceptionCode.SMS_CODE_SEND_LIMITED,remainLimitTime);
        }


    }


    /**
     * 短信验证码校验
     */
    public CheckSmsCodeVO checkSmsCode(CheckSmsCodeData checkSmsCodeData) {

        boolean result = checkVerifyCode(checkSmsCodeData.getUserType(),
                checkSmsCodeData.getOperationType(),
                checkSmsCodeData.getAreaCode(),
                checkSmsCodeData.getMobile(),
                checkSmsCodeData.getCode());

        if (result) {

            //存储密码变更token
            String pwdChangeToken = UUID.randomUUID().toString();

            smsVerifyCodeRepository.savePwdChangeToken(checkSmsCodeData.getUserType(),
                    checkSmsCodeData.getAreaCode(),
                    checkSmsCodeData.getMobile(),
                    pwdChangeToken,Constant.PWD_CHANGE_TOKEN_EXPIRE_TIME);

            return new CheckSmsCodeVO(true,pwdChangeToken);

        } else {
            throw ApplicationException.error(ApplicationExceptionCode.SMS_CODE_VALID_FAIL);
        }



    }

    public boolean checkVerifyCode(UserType userType, OperationType operationType, String areaCode, String mobile, String printCode) {


        if (env.equals("dev") || env.equals("pre") || env.equals("test")) {
            return "0000".equals(printCode);
        }

        String code = smsVerifyCodeRepository.querySmsVerifyCode(userType,operationType,areaCode,mobile);

        if (!StringUtils.isEmpty(code) && code.equals(printCode)) {
            //删除短信验证码缓存
            smsVerifyCodeRepository.delSmsVerifyCode(userType,
                    operationType,
                    areaCode,
                    mobile);

            return true;
        }

        return false;

    }

}
